package com.goodmr.passport.webapp.resolver;

import com.goodmr.passport.annotation.AuthUserId;
import com.goodmr.passport.enums.HeaderEnum;
import com.goodmr.passport.webapp.enums.ErrorEnum;
import com.goodmr.passport.webapp.exception.UnauthorizedException;
import org.philcode.toolkit.core.util.StringUtils;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletRequest;

/**
 * 通过 @AuthUserId 注解
 * 反射获取已鉴权过的用户ID
 *
 * @author <a href="mailto:bingdong13@msn.com">bigo</a>
 */
@Component
public class UserIdResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameterType().equals(Long.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter,
                                  ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest,
                                  WebDataBinderFactory binderFactory) {

        Long userId = null;

        if (parameter.hasParameterAnnotation(AuthUserId.class)) {

            HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
            String userIdString = request.getHeader(HeaderEnum.X_USER_ID.getValue());

            if (StringUtils.isNotBlank(userIdString)) {
                userId = Long.valueOf(userIdString);
            } else {

                String authorization = request.getHeader(HeaderEnum.AUTHORIZATION.getValue());

                // todo 从鉴权服务解析 authorization
                userId = 0L;
            }

            if (userId <= 0) {
                throw new UnauthorizedException(ErrorEnum.UNAUTHORIZED);
            }
        }

        return userId;
    }
}

